//
//  lameTool.m
//  01- 录音
//
//  Created by 王顺子 on 16/4/3.
//  Copyright © 2016年 小码哥. All rights reserved.
//

#import "LameTool.h"
#import "lame.h"

@implementation LameTool

+ (NSString *)convertToMp3: (NSString *)audioSourcePath isDeleteSourceFile:(BOOL)isDelete {
    // 输入路径
    NSString *inPath = audioSourcePath;

    // 判断输入路径是否存在
    NSFileManager *fm = [NSFileManager defaultManager];
    if (![fm fileExistsAtPath:audioSourcePath]) {
        NSLog(@"文件不存在");
    }

    // 输出路径
    NSString *outPath = [[audioSourcePath stringByDeletingPathExtension] stringByAppendingString:@".mp3"];


    @try {
        int read, write;

        //source 被转换的音频文件位置(FILE文件指针名,"rb": 使用文件的方式)
        FILE *pcm = fopen([inPath cStringUsingEncoding:1], "rb");
        //skip file header重定位流上的文件指针,(描 述: 函数设置文件指针stream的位置。如果执行成功，stream将指向以fromwhere为基准，偏移offset个字节的位置。如果执行失败(比如offset超过文件自身大小)，则不改变stream指向的位置。返回值: 成功，返回0，否则返回其他值。)
        fseek(pcm, 4*1024, SEEK_CUR);
        //output 输出生成的Mp3文件位置
        FILE *mp3 = fopen([outPath cStringUsingEncoding:1], "wb");

        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE*2];
        unsigned char mp3_buffer[MP3_SIZE];

        //这里要注意，lame的配置要跟AVAudioRecorder的配置一样，否则会造成转换失败
        lame_t lame = lame_init();
        //设置1为单通道，默认为2双通道（录音时是双通道）
        //lame_set_num_channels(lame,2);
        //设置被输入编码器的原始数据的采样率。
        lame_set_in_samplerate(lame, 11025.0);
        //设置比特率控制模式，默认是CBR，但是通常我们都会设置VBR。参数是枚举，vbr_off代表CBR，vbr_abr代表ABR（因为ABR不常见，所以本文不对ABR做讲解）vbr_mtrh代表VBR。
        lame_set_VBR(lame, vbr_default);
        //根据上面设置好的参数建立编码器
        lame_init_params(lame);

        do {
            size_t size = (size_t)(2 * sizeof(short int));
            //fread是一个函数。从一个文件流中读数据，最多读取count个元素，每个元素size字节，如果调用成功返回实际读取到的元素个数，如果不成功或读到文件末尾返回 0。
            read = (int)fread(pcm_buffer, size, PCM_SIZE, pcm);
            if (read == 0){
                //刷新编码器缓冲，获取残留在编码器缓冲里的数据。这部分数据也需要写入mp3文件
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            }else{
                //将PCM数据送入编码器，获取编码出的mp3数据。这些数据写入文件就是mp3文件。
                write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
            }
            //写入文件
            fwrite(mp3_buffer, write, 1, mp3);
        } while (read != 0);
        //将VBR/INFO tags封装到一个MP3 Frame中，写到文件开头。如果输出流没有办法回溯，那么必须在第3步设置lame_set_bWriteVbrTag(gfp,0)，这一步调用lame_mp3_tags_fid(lame_global_flags *,FILE* fid)将fid参数＝NULL。这样的话那个开头的信息帧（MP3 FRAME）的所有字节都是0。
        //lame_mp3_tags_fid(lame, mp3);
        
        lame_close(lame);
        fclose(mp3);
        fclose(pcm);
    }
    @catch (NSException *exception) {
        NSLog(@"%@",[exception description]);
    }
    @finally {
        NSLog(@"MP3生成成功:");
        if (isDelete) {

            NSError *error;
            [fm removeItemAtPath:audioSourcePath error:&error];
            if (error == nil) {
                NSLog(@"删除源文件成功");
            }
        }
        return outPath;
    }
}



@end
